<template>
    <el-dialog v-model="dialogVisible" :title="title" :width="width" :destroy-on-close="destroyOnClose"
        :draggable="true" :close-on-click-modal="true" :close-on-press-escape="true">

        <!-- 添加一级目录按钮 -->
        <div class="mb-5">
            <el-button @click="showAddCatalogDialog" type="primary">
                <el-icon class="mr-1">
                    <Plus />
                </el-icon>
                添加目录</el-button>
        </div>

        <!-- 内容 -->
        <div id="accordion-flush" data-accordion="collapse"
            data-active-classes="bg-white dark:bg-gray-900 text-gray-900 dark:text-white"
            data-inactive-classes="text-gray-500 dark:text-gray-400">
            <h2 v-for="(item, index) in catalogs" :key="item.id" id="accordion-flush-heading-1">
                <!-- 一级目录 -->
                <button type="button" class="transition-all duration-300 hover:bg-gray-100 py-2 px-3 rounded-lg flex items-center w-full font-medium rtl:text-right 
                    text-gray-500 dark:border-gray-700 dark:text-gray-400"
                    data-accordion-target="#accordion-flush-body-1" aria-expanded="true"
                    aria-controls="accordion-flush-body-1">
                    <svg data-accordion-icon class="w-3 h-3 mr-2 rotate-180 shrink-0" aria-hidden="true"
                        xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
                        <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M9 5 5 1 1 5" />
                    </svg>
                    <!-- 一级目录标题 -->
                    <span v-if="!item.editing" class="flex items-center grow" v-html="item.title"></span>
                    <!-- 操作 -->
                    <span v-else class="w-full">
                        <el-input @keyup.enter="onEditTitleInputBlur(item.id)" @blur="onEditTitleInputBlur(item.id)" v-model="item.title" placeholder="请输入目录标题"
                            clearable />
                    </span>

                    <!-- 操作搜索图标 -->
                    <div class="transition-all duration-300 size-6 hover:bg-blue-400 rounded-[50%]  py-[4px] px-[4px]">
                        <!-- 下拉菜单 -->
                        <el-dropdown @command="handleCommand">
                            <span class="dropdown-icon el-dropdown-link">
                                <svg t="1705472726484" class="icon size-4 outline-none" viewBox="0 0 1024 1024"
                                    version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5968">
                                    <path
                                        d="M512 298.6496a85.3504 85.3504 0 1 0 0-170.6496 85.3504 85.3504 0 0 0 0 170.6496z"
                                        fill="#707070" p-id="5969"></path>
                                    <path
                                        d="M512 512m-85.3504 0a85.3504 85.3504 0 1 0 170.7008 0 85.3504 85.3504 0 1 0-170.7008 0Z"
                                        fill="#707070" p-id="5970"></path>
                                    <path
                                        d="M512 896a85.3504 85.3504 0 1 0 0-170.7008 85.3504 85.3504 0 0 0 0 170.7008z"
                                        fill="#707070" p-id="5971"></path>
                                </svg>
                            </span>
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <el-dropdown-item :command="{ id: item.id, sort: item.sort, action: 'rename' }">
                                        <el-icon>
                                            <EditPen />
                                        </el-icon>
                                        重命名
                                    </el-dropdown-item>
                                    <el-dropdown-item :command="{ id: item.id, sort: item.sort, action: 'addArticle' }">
                                        <el-icon>
                                            <Plus />
                                        </el-icon>
                                        添加文章
                                    </el-dropdown-item>
                                    <el-dropdown-item v-if="(index + 1) > 1"
                                        :command="{ id: item.id, sort: item.sort, action: 'moveUp' }">
                                        <el-icon>
                                            <Top />
                                        </el-icon>
                                        上移
                                    </el-dropdown-item>
                                    <el-dropdown-item v-if="(index + 1) < catalogs.length"
                                        :command="{ id: item.id, sort: item.sort, action: 'moveDown' }">
                                        <el-icon>
                                            <Bottom />
                                        </el-icon>
                                        下移
                                    </el-dropdown-item>
                                    <el-dropdown-item divided
                                        :command="{ id: item.id, sort: item.sort, action: 'remove' }">
                                        <el-icon>
                                            <DocumentRemove />
                                        </el-icon>
                                        移出目录
                                    </el-dropdown-item>
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                    </div>
                </button>

                <!-- 二级目录 -->
                <ul>
                    <VueDraggable ref="el" v-model="item.children" @end="onDragEnd">
                        <li v-for="(child, index) in item.children" :key="child.id"
                            class="transition-all duration-300 flex items-center ps-10 pe-3 rounded-lg hover:bg-gray-100">
                            <span v-if="!child.editing" class="grow" v-html="child.title"></span>
                            <span v-else class="grow">
                                <el-input @keyup.enter="onEditTitleInputBlur(child.id)"
                                    @blur="onEditTitleInputBlur(child.id)" v-model="child.title" placeholder="请输入目录标题"
                                    clearable />
                            </span>

                            <!-- 重命名 -->
                            <span @click="handleCommand({ id: child.id, sort: child.sort, action: 'rename' })"
                                class="transition-all duration-500 rounded-full hover:bg-gray-200 py-2 px-2 ml-2 mr-2">
                                <svg t="1705474417719" class="icon w-4 h-4" viewBox="0 0 1024 1024" version="1.1"
                                    xmlns="http://www.w3.org/2000/svg" p-id="8306" width="200" height="200">
                                    <path
                                        d="M402.24 753.12l417.984-417.952a35.552 35.552 0 0 0 0-50.304l-75.424-75.424a35.552 35.552 0 0 0-50.304 0L276.576 627.392l-8.992 134.72 134.688-8.992zM193.664 801.92l13.76-205.92L644.192 159.168a106.656 106.656 0 0 1 150.848 0l75.424 75.424a106.656 106.656 0 0 1 0 150.848L433.632 822.304l-205.92 13.728A32 32 0 0 1 193.6 801.92zM644.224 259.744l-50.272 50.24 125.696 125.76 50.272-50.304-125.696-125.696z"
                                        fill="#707070" p-id="8307"></path>
                                </svg>
                            </span>
                            <!-- 删除 -->
                            <el-tooltip class=" box-item" effect="dark" content="移出目录" placement="right">
                                <span @click="removeArticleFromCatalog(child.id)"
                                    class="transition-all duration-500 rounded-full hover:bg-gray-200 py-2 px-2">
                                    <svg t="1705473517473" class="icon w-4 h-4" viewBox="0 0 1024 1024" version="1.1"
                                        xmlns="http://www.w3.org/2000/svg" p-id="7174" width="200" height="200">
                                        <path
                                            d="M607.897867 768.043004c-17.717453 0-31.994625-14.277171-31.994625-31.994625L575.903242 383.935495c0-17.717453 14.277171-31.994625 31.994625-31.994625s31.994625 14.277171 31.994625 31.994625l0 351.94087C639.892491 753.593818 625.61532 768.043004 607.897867 768.043004z"
                                            fill="#707070" p-id="7175"></path>
                                        <path
                                            d="M415.930119 768.043004c-17.717453 0-31.994625-14.277171-31.994625-31.994625L383.935495 383.935495c0-17.717453 14.277171-31.994625 31.994625-31.994625 17.717453 0 31.994625 14.277171 31.994625 31.994625l0 351.94087C447.924744 753.593818 433.647573 768.043004 415.930119 768.043004z"
                                            fill="#707070" p-id="7176"></path>
                                        <path
                                            d="M928.016126 223.962372l-159.973123 0L768.043004 159.973123c0-52.980346-42.659499-95.983874-95.295817-95.983874L351.94087 63.989249c-52.980346 0-95.983874 43.003528-95.983874 95.983874l0 63.989249-159.973123 0c-17.717453 0-31.994625 14.277171-31.994625 31.994625s14.277171 31.994625 31.994625 31.994625l832.032253 0c17.717453 0 31.994625-14.277171 31.994625-31.994625S945.73358 223.962372 928.016126 223.962372zM319.946246 159.973123c0-17.545439 14.449185-31.994625 31.994625-31.994625l320.806316 0c17.545439 0 31.306568 14.105157 31.306568 31.994625l0 63.989249L319.946246 223.962372 319.946246 159.973123 319.946246 159.973123z"
                                            fill="#707070" p-id="7177"></path>
                                        <path
                                            d="M736.048379 960.010751 288.123635 960.010751c-52.980346 0-95.983874-43.003528-95.983874-95.983874L192.139761 383.591466c0-17.717453 14.277171-31.994625 31.994625-31.994625s31.994625 14.277171 31.994625 31.994625l0 480.435411c0 17.717453 14.449185 31.994625 31.994625 31.994625l448.096758 0c17.717453 0 31.994625-14.277171 31.994625-31.994625L768.215018 384.795565c0-17.717453 14.277171-31.994625 31.994625-31.994625s31.994625 14.277171 31.994625 31.994625l0 479.231312C832.032253 916.835209 789.028725 960.010751 736.048379 960.010751z"
                                            fill="#707070" p-id="7178"></path>
                                    </svg>
                                </span>
                            </el-tooltip>
                        </li>
                    </VueDraggable>
                </ul>
            </h2>
        </div>
    </el-dialog>

    <!-- 添加目录 -->
    <FormDialog ref="addCatalogDialogRef" title="添加目录" destroyOnClose @submit="onAddCatalogSubmit">
        <el-form ref="addCatalogFormRef" :rules="rules" :model="addCatalogForm">
            <el-form-item label="标题" prop="title" label-width="80px" size="default">
                <el-input @keyup.enter="onAddCatalogSubmit" v-model="addCatalogForm.title" placeholder="请输入目录标题"
                    clearable />
            </el-form-item>
        </el-form>
    </FormDialog>

    <!-- 给目录添加文章 -->
    <FormDialog ref="addArticleToDialogRef" width="70%" title="添加文章" destroyOnClose @submit="onAddArticleSubmit">
        <div>
            <!-- 表头分页查询条件， shadow="never" 指定 card 卡片组件没有阴影 -->
            <el-card shadow="never" class="mb-5">
                <!-- flex 布局，内容垂直居中 -->
                <div class="flex items-center">
                    <el-text>文章标题</el-text>
                    <div class="ml-3 w-52 mr-5"><el-input v-model="searchArticleTitle" placeholder="请输入（模糊查询）"
                            clearable />
                    </div>

                    <el-text>创建日期</el-text>
                    <div class="ml-3 w-30 mr-5">
                        <!-- 日期选择组件（区间选择） -->
                        <el-date-picker v-model="pickDate" type="daterange" range-separator="至" start-placeholder="开始时间"
                            end-placeholder="结束时间" size="default" :shortcuts="shortcuts" @change="datepickerChange" />
                    </div>

                    <el-button type="primary" class="ml-3" :icon="Search" @click="getTableData">查询</el-button>
                    <el-button class="ml-3" :icon="RefreshRight" @click="reset">重置</el-button>
                </div>
            </el-card>

            <el-card shadow="never">
                <!-- 分页列表 -->
                <el-table :data="tableData" @selection-change="handleSelectionChange" border stripe v-loading="tableLoading">
                    <!-- 可选符 -->
                    <el-table-column type="selection" width="45" />
                    <el-table-column prop="id" label="ID" width="50" />
                    <el-table-column prop="title" label="标题" width="380" />
                    <el-table-column prop="cover" label="封面" width="180">
                        <template #default="scope">
                            <el-image style="width: 100px;" :src="scope.row.cover" />
                        </template>
                    </el-table-column>

                    <el-table-column prop="isPublish" label="是否发布" width="100">
                        <template #default="scope">
                            <el-switch v-model="scope.row.isPublish" inline-prompt :active-icon="Check"
                                :inactive-icon="Close" disabled />
                        </template>
                    </el-table-column>
                    <el-table-column prop="createTime" label="发布时间" />
                </el-table>

                <!-- 分页 -->
                <div class="mt-10 flex justify-center">
                    <el-pagination v-model:current-page="current" v-model:page-size="size" :page-sizes="[5,10,20]"
                        :small="false" :background="true" layout="total, sizes, prev, pager, next, jumper"
                        :total="total" @size-change="handleSizeChange" @current-change="getTableData" />
                </div>

            </el-card>


        </div>
    </FormDialog>

</template>

<script setup>
import { showConfirm, showMessage } from '@/composables/utils';
import { Close, Check, Search, RefreshRight } from '@element-plus/icons-vue';
import { reactive, ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus';
import FormDialog from './FormDialog.vue';
import { getArticlePageList } from '@/api/admin/article';
import { getWikiCatalogs, updateWikiCatalogs } from '@/api/admin/wiki';


//===============================时间查询=================================
const startDate = ref(null)
const endDate = ref(null)
const pickDate = ref([])
const shortcuts = [
    {
        text: '最近一周',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            return [start, end]
        },
    },
    {
        text: '最近一个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            return [start, end]
        }
    },
    {
        text: '最近三个月',
        value: () => {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            return [start, end]
        }
    }
]
const datepickerChange = (e) => {
    startDate.value = moment(e[0]).format('YYYY-MM-DD')
    endDate.value = moment(e[1]).format('YYYY-MM-DD')
    console.log('开始时间：' + startDate.value + ', 结束时间：' + endDate.value)
}




// 对话框是否显示
const dialogVisible = ref(false)


//===============================目录数据=================================
const catalogs = ref([])
const currWikiId = ref(null)
const getCatalogs = ()=>{
    getWikiCatalogs(currWikiId.value).then(res=>{
        if(!res.success){
            showMessage(res.msg, 'error')
            return
        }
        catalogs.value = res.data
    })
}

// 编辑目录title
const currCatalogId = ref(null)
const handleCommand = (command) => {
    if (command.action == 'rename') {   // 重命名Wiki
        editTitle(command.id)
    } else if (command.action == 'remove') {   // 移出Wiki
        removeCatalogConfirm(command.id)
    } else if (command.action == 'moveUp') {   // 上移Wiki
        catalogMove(command.id, command.sort, 'up')
    } else if (command.action == 'moveDown') {   // 下移Wiki
        catalogMove(command.id, command.sort, 'down')
    } else if (command.action == 'addArticle') {   // 添加文章
        currCatalogId.value = command.id
        getTableData()
        addArticleToDialogRef.value.showDialog()
    }
}
// =====================================编辑标题=================================
const editTitle = (catalogId) => {
    // 根据目录 ID 查找对应的目录
    let targetCatalog = findCatalogById(catalogs.value, catalogId)
    if (targetCatalog == null) {
        showMessage('未找到对应的目录', 'error')
        return
    }
    // 将编辑状态置为 true
    targetCatalog.editing = true
}
// 查找对应的目录
const findCatalogById = (catalogs, catalogId) => {
    for (const catalog of catalogs) {
        if (catalog.id == catalogId) {
            return catalog
        }
        if (catalog.children && catalog.children.length > 0) {
            let targetCatalog = findCatalogById(catalog.children, catalogId)
            if (targetCatalog) {
                return targetCatalog
            }
        }
    }
    return null
}
// 编辑目录title Input 失去焦点事件
const onEditTitleInputBlur = (catalogId) => {
    let targetCatalog = findCatalogById(catalogs.value, catalogId)
    // 将编辑状态置为 false
    targetCatalog.editing = false
    // 给个默认的标题, 三元表达式
    targetCatalog.title = targetCatalog.title ? targetCatalog.title : '未命名'
    // 更新目录
    updateWikiCatalogsData()
}
// ==================================删除目录================================
const removeCatalogConfirm = (catalogId) => {  // 移除目录函数
    showConfirm('确定要删除这个目录吗').then(() => {
        removeCatalog(catalogs.value, catalogId)
        updateWikiCatalogsData() // 更新目录
    }).catch(() => {
        showMessage('取消删除', 'info')
    })
}
const removeCatalog = (catalogs, catalogId) => { //删除一级目录逻辑
    for (let i = 0; i < catalogs.length; i++) {
        const catalog = catalogs[i]
        if (catalog.id == catalogId) {    // 一级目录删除
            catalogs.splice(i, 1)
            return catalogs
        }
        if (catalog.children && catalog.children.length > 0) {    // 删除一级目录时要将对应的二级目录删除
            removeCatalog(catalog.children, catalogId)
        }
    }
    return catalogs;
}
// 移除二级目录
const removeArticleFromCatalog = (catalogId) => {
    showConfirm('确定要删除这个文章吗').then(() => {
        removeCatalog(catalogs.value, catalogId)
        updateWikiCatalogsData()    // 更新目录
    }).catch(() => {
        showMessage('取消删除', 'info')
    })
}
// ==================================交换目录================================
// 就是将两个一级目录的 sort值更换
const catalogMove = (catalogId, sort, direction) => {
    let sourceCatalog = findCatalogById(catalogs.value, catalogId)  // 要移动的目录
    if (sourceCatalog == null) {
        showMessage('未找到对应的目录', 'error')
        return
    }
    let targetCatalog = getCatalogBySort(sort, direction)
    if (targetCatalog == null) {
        showMessage('未找到对应的目录??', 'error')
        return
    }
    let sourceSort = sourceCatalog.sort // 要移动的目录的排序号
    let targetSort = targetCatalog.sort // 目标目录的排序号
    // 互换排序号
    sourceCatalog.sort = targetSort
    targetCatalog.sort = sourceSort
    // 重新排序
    sortCatalogs()
    console.log(catalogs.value)
    updateWikiCatalogsData()    // 更新目录
}
const getCatalogBySort = (sort, direction) => {
    if (direction == 'up') {
        const tmpCatalogs = [...catalogs.value]
        for (const catalog of tmpCatalogs.reverse()) {
            if (catalog.sort < sort) {
                return catalog  // 返回目标目录 返回它
            }
        }
    } else if (direction == 'down') {
        for (const catalog of catalogs.value) {
            if (catalog.sort > sort) {
                return catalog  // 返回目标目录 返回它
            }
        }
    }
    return null
}
const sortCatalogs = () => {
    catalogs.value = catalogs.value.sort((a, b) => a.sort - b.sort)
}

// 二级目录拖拽交换 =====> VueDraggablePlus
const onDragEnd = () => {
    updateWikiCatalogsData()    // 更新目录
}
// ==================================新增目录================================
const addCatalogDialogRef = ref(null)
const addCatalogFormRef = ref(null)
const rules = {
    title: [
        {
            required: true,
            message: '目录标题不能为空',
            trigger: 'blur',
        },
    ]
}
const addCatalogForm = reactive({
    title: ''
})
const showAddCatalogDialog = () => {
    addCatalogDialogRef.value.showDialog()
}
const tmpId = ref(-1)   //临时id
const onAddCatalogSubmit = () => {  // 提交新增
    addCatalogFormRef.value.validate((valid) => {
        if (!valid) {
            showMessage('表单校验失败', 'error')
            return
        }
        let lastCatalog = catalogs.value[catalogs.value.length - 1] // 最后一个目录
        let newCatalog = {
            id: tmpId.value,
            title: addCatalogForm.title,
            editing: false,
            level: 1,
            sort: lastCatalog.sort + 1,
            children: []
        }
        catalogs.value.push(newCatalog)
        tmpId.value -= 1
        addCatalogDialogRef.value.closeDialog()
        addCatalogForm.title = ''
        // 新增成功, 更新目录, 将数据同步到数据库
        updateWikiCatalogsData()
        showMessage('新增目录成功', 'success')
    })
}
// ==================================目录 && 文章操作================================
const selectionArticles = ref([])   //选中的文章
const handleSelectionChange = (val) => {    // 监听选择文章事件
    console.log(val)
    selectionArticles.value = val
}
// ==================================给目录新增文章(新增二级目录)================================
const addArticleToDialogRef = ref(null)
const tableData = ref([])
const tableLoading = ref(false)
const current = ref(1)
const size = ref(10)
const total = ref(0)
const searchArticleTitle = ref('')

// 获取文章列表
const getTableData = () => {
    tableLoading.value = true
    getArticlePageList({    // 获取不属于知识库的文章,这样之后就可以调整
        current: current.value, 
        size: size.value,
        startDate: startDate.value,
        endDate: endDate.value ,
        title: searchArticleTitle.value,
        type: 1 
    }).then(res => {
        tableData.value = res.data
        total.value = res.total
        current.value = res.current
        size.value = res.size
    }).finally(() => {
        tableLoading.value = false
    })
}
const handleSizeChange = (chooseSize) => {
    size.value = chooseSize
    getTableData()
}
// 添加文章到目录
const onAddArticleSubmit = () => {  //  提交新增
    if (selectionArticles.value.length == 0) {  // 检测是否选中文章
        showMessage('请选择文章', 'warning')
        return
    }
    for(const catalog of catalogs.value) {
        if (catalog.id == currCatalogId.value) {
            for (const article of selectionArticles.value) {
                let articleTitle = article.title
                let newCatalog = {  // 构建二级目录
                    id: tmpId.value,
                    articleId: article.id,
                    title: articleTitle,
                    editing: false,
                    level: 2
                }
                catalog.children.push(newCatalog)
                tmpId.value -= 1
            }
        }
    }
    updateWikiCatalogsData()    // 更新目录
    addArticleToDialogRef.value.closeDialog()
    selectionArticles.value = []    // 清空选中的文章
}
// ============更新目录数据方法============
const updateWikiCatalogsData = ()=>{
    updateWikiCatalogs({
        id: currWikiId.value,   // 要更新的知识库id
        catalogs: catalogs.value
    }).then(res => {
        console.log(res)
        if (!res.success) { // 更新失败
            showMessage(res.message, 'error')
            return
        }
        getCatalogs()
    })
}









const reset = () => {
    pickDate.value = ''
    startDate.value = null
    endDate.value = null
    searchArticleTitle.value = ''
}

// 确认按钮加载 loading
const btnLoading = ref(false)
// 显示 loading
const showBtnLoading = () => btnLoading.value = true
// 隐藏 loading
const closeBtnLoading = () => btnLoading.value = false

// 对外暴露属性
const props = defineProps({
    title: String,
    width: {
        type: String,
        default: '40%'
    },
    destroyOnClose: {
        type: Boolean,
        default: false
    },
    confirmText: {
        type: String,
        default: '提交'
    }
})

// 打开
const open = (wikiId) => {
    dialogVisible.value = true
    console.log("知识库 ID: " + wikiId)
    currWikiId.value = wikiId   // 当前知识库id
    getCatalogs()
}
// 关闭
const close = () => dialogVisible.value = false

// 对外暴露方法
defineExpose({
    open,
    close,
    showBtnLoading,
    closeBtnLoading
})
</script>

<style scoped>
.dropdown-icon:focus-visible{
    outline: none;
}
</style>